/*
私有方法和私有属性，是只能在类的内部访问的方法和属性，外部不能访问。
这是常见需求，有利于代码的封装，但 ES6 不提供，只能通过变通方法模拟实现。

一种做法是在命名上加以区别。

_bar()方法前面的下划线，表示这是一个只限于内部使用的私有方法。
但是，这种命名是不保险的，在类的外部，还是可以调用到这个方法。
*/
class Widget {

	// 公有方法
	foo(baz) {
		this._bar(baz);
	}

	// 私有方法
	_bar(baz) {
		return this.snaf = baz; // 当前没有this.snaf  所以此步操作是声明snaf
	}

	// ...
}



/*
另一种方法就是索性将私有方法移出类，因为类内部的所有方法都是对外可见的。
foo是公开方法，内部调用了bar.call(this, baz)。
这使得bar()实际上成为了当前类的私有方法。

源码还是要靠 call bind apply啊
*/
class Widget {
	foo(baz) {
		bar.call(this, baz);
	}

	// ...
}

function bar(baz) {
	return this.snaf = baz;
}

/*
还有一种方法是利用Symbol值的唯一性，将私有方法的名字命名为一个Symbol值。
bar和snaf都是Symbol值，一般情况下无法获取到它们，因此达到了私有方法和私有属性的效果。
但是也不是绝对不行，Reflect.ownKeys()依然可以拿到它们。
*/

const bar = Symbol('bar'); //symbol常与[]搭配使用  多用户命名规范  说到底像是一个独一无二的字符串 在访问时用[]
const snaf = Symbol('snaf');

export default class myClass {

	// 公有方法
	foo(baz) {
		this[bar](baz); //注意是用了[]
	}

	// 私有方法
	[bar](baz) {
		return this[snaf] = baz;
	}

	// ...
};
const inst = new myClass();

Reflect.ownKeys(myClass.prototype)
// [ 'constructor', 'foo', Symbol(bar) ]
//上面代码中， Symbol 值的属性名依然可以从类的外部拿到。



/*
私有属性的提案
以后再学习
*/
